using System;

using Microsoft.SharePoint;

using RealDolmen.SharePoint.Helpers;

namespace RealDolmen.SharePoint.ListFeatures.Elements
{
    public class ListFeatureEventElement : ListFeatureElement, IListFeatureTrackerReferencee
    {
        public static string RootTag
        {
            get { return "Receiver"; }
        }

        #region Overrides
        public override string FullKey
        {
            get { return ListFeatureKeyManager.GenerateDottedKey("Receivers", Key); }
        }

        public override string Key
        {
            get { return Name; }
        }

        public override bool Customizable
        {
            get { return false; }
        } 
        #endregion // Overrides

        #region Activate / Deactivate
        public override void Activate(ListFeature listFeature)
        {
            SPEventReceiverDefinition eventReceiver = listFeature.ParentList.EventReceivers.Add();
            eventReceiver.Assembly = Assembly;
            eventReceiver.Class = Class;
            eventReceiver.Type = Type;
            eventReceiver.Filter = Filter;
            eventReceiver.Name = Name;

            // At the moment, we don't support granular custom sequence numbers
            Random r = new Random();
            eventReceiver.SequenceNumber = SequenceNumber + r.Next(100);

            UpdateTrackerReference(listFeature, eventReceiver, Data);

            SPWeb web = listFeature.ParentList.ParentWeb;
            {
                web.AllowUnsafeUpdates = true;
                eventReceiver.Update();
                web.AllowUnsafeUpdates = false;
            }
            // SPHelper.TryDisposeWeb(web);
        }

        public override void Deactivate(ListFeature listFeature)
        {
            bool match = false;

            SPEventReceiverDefinitionCollection definitions = listFeature.ParentList.EventReceivers;
            for (int i = 0; i < definitions.Count; i++)
            {
                SPEventReceiverDefinition definition = definitions[i];
                match = definition.Assembly == Assembly && definition.Class == Class && definition.Type == Type;
                match |= definition.Name == Name && definition.Type == Type;

                if(match)
                    definition.Delete();
            }
        } 
        #endregion // Activate / Deactivate

        #region Public Properties
        public string Assembly
        {
            get { return XmlDefinition["Assembly"].InnerText; }
        }

        public string Class
        {
            get { return XmlDefinition["Class"].InnerText; }
        }

        public string Name
        {
            get { return XmlDefinition["Name"].InnerText; }
        }

        public string TypeString
        {
            get { return XmlDefinition["Type"].InnerText; }
        }

        public SPEventReceiverType Type
        {
            get { return (SPEventReceiverType)Enum.Parse(typeof(SPEventReceiverType), TypeString); }
        }

        public string SequenceNumberString
        {
            get { return XmlDefinition["SequenceNumber"].InnerText; }
        }

        public int SequenceNumber
        {
            get { return int.Parse(SequenceNumberString); }
        }

        public string Data
        {
            get { return XmlDefinition["Data"].InnerText; }
        }

        public string Filter
        {
            get { return XmlDefinition["Filter"].InnerText; }
        } 
        #endregion // Public Properties

        #region IListFeatureTrackerReferencee Members
        public void UpdateTrackerReference(ListFeature listFeature, string oldTrackerData)
        {
            SPWeb web = listFeature.ParentList.ParentWeb;
            {
                web.AllowUnsafeUpdates = true;
                for (int i = 0; i < listFeature.ParentList.EventReceivers.Count; i++)
                {
                    SPEventReceiverDefinition eventReceiver = listFeature.ParentList.EventReceivers[i];
                    if (eventReceiver.Data.StartsWith(oldTrackerData))
                    {
                        UpdateTrackerReference(listFeature, eventReceiver, Data);
                        eventReceiver.Update();
                    }
                }
                web.AllowUnsafeUpdates = false;
            }
            // SPHelper.TryDisposeWeb(web);
        }
        private static void UpdateTrackerReference(ListFeature listFeature, SPEventReceiverDefinition eventReceiver, string originalData)
        {
            eventReceiver.Data = new ListFeatureCompiledReceiverData(listFeature.TrackerData, originalData).Compiled;
        }
        #endregion
    }
}